PageRenderTime 47ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/[Include]/HardcodeVB/Components/Random.cls

https://gitlab.com/badcodes/vb6
Visual Basic for Applications | 164 lines | 90 code | 17 blank | 57 comment | 0 complexity | 1947d10a9eb99c9611d90f08153aeff8 MD5 | raw file
  1. VERSION 1.0 CLASS
  2. BEGIN
  3. MultiUse = -1 'True
  4. Persistable = 0 'NotPersistable
  5. DataBindingBehavior = 0 'vbNone
  6. DataSourceBehavior = 0 'vbNone
  7. MTSTransactionMode = 0 'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "GRandom"
  10. Attribute VB_GlobalNameSpace = True
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = True
  14. Option Explicit
  15. Public Enum EErrorRandom
  16. eeBaseRandom = 13580 ' Random
  17. eeBaseIllegalRange ' Random: Range can't be greater than 2147483645
  18. End Enum
  19. ' For Random algorithm
  20. Private iLast As Long
  21. Private iSeed As Long
  22. Private Const A As Long = 48271
  23. Private Const M As Long = 2147483647
  24. Private Const MAX As Long = 2147483645
  25. Private Const Q As Long = (M / A)
  26. Private Const R As Long = (M Mod A)
  27. Private Const rT As Single = 1# / MAX
  28. ' VB6 verions includes fixes suggested by Lynn Torkelson
  29. Private Sub Class_Initialize()
  30. Seed 0
  31. End Sub
  32. ' Pedigree for the Random and Seed algorithms
  33. '****************************************************************************
  34. '* PMMMLCG - Prime Modulus M Multiplicative Linear Congruential Generator *
  35. '* Modified version of the random number generator proposed by *
  36. '* Park & Miller in "Random Number Generators: Good Ones Are Hard to Find" *
  37. '* CACM October 1988, Vol 31, No. 10 *
  38. '* - Modifications proposed by Park to provide better statistical *
  39. '* properties (i.e. more "random" - less correlation between sets of *
  40. '* generated numbers *
  41. '* - generator is of the form *
  42. '* x = ( x * A) % M *
  43. '* - Choice of A & M can radically modify the properties of the generator *
  44. '* the current values were chosen after followup work to the original *
  45. '* paper mentioned above. *
  46. '* - The generator has a period of 2^31 - 1 with numbers generated in the *
  47. '* range of 0 < x < M *
  48. '* - The generator can run on any machine with a 32-bit integer, without *
  49. '* overflow. *
  50. '* - This generator is currently running on Sun 3/50, Sparc, IBM PC/XT, *
  51. '* IBM RS/6000 just to name a few... *
  52. '****************************************************************************
  53. '* John Burton *
  54. '* G & A Technical Software, Inc *
  55. '* 28 Research Drive *
  56. '* Hampton, Va. 23666 *
  57. '* *
  58. '* jcburt@cs.wm.edu *
  59. '* jcburt@gatsibm.larc.nasa.gov *
  60. '* burton@asdsun.larc.nasa.gov *
  61. '****************************************************************************
  62. '* Random() - return next random number
  63. '*
  64. '* The Random() subroutine returns a pseudo-random long value in
  65. '* the range Min <= x < Max
  66. Function Random(Optional ByVal iMin As Long = 0, _
  67. Optional ByVal iMax As Long = MAX) As Long
  68. Dim iLo As Long, iHi As Long, iT As Long
  69. #If fComponent = 0 Then
  70. If iLast = 0 Then Class_Initialize
  71. #End If
  72. ' Can't have range larger than 2147483645
  73. If Abs(iMax - iMin) > MAX Then ErrRaise eeBaseIllegalRange
  74. iHi = iLast / Q
  75. iLo = iLast Mod Q
  76. iT = (A * iLo) - (R * iHi)
  77. If iT >= 0 Then
  78. iLast = iT
  79. Else
  80. iLast = iT + M
  81. End If
  82. ' Range is 1-2147483646; adjust range to 0-2147483645
  83. Random = iLast - 1
  84. If iMin <> 0 Or iMax <> MAX Then
  85. If iMin < iMax Then
  86. Random = iMin + ((iLast - 1) Mod (iMax - iMin + 1))
  87. Else
  88. Random = iMax + ((iLast - 1) Mod (iMin - iMax + 1))
  89. End If
  90. End If
  91. End Function
  92. '* RandomReal() - return next random number
  93. '*
  94. '* The RandomReal() function returns a pseudo-random floating point value
  95. '* in the range 0.0 <= x < 1.0.
  96. Function RandomReal() As Single
  97. RandomReal = CSng(Random * rT)
  98. End Function
  99. '* Seed - Set first random number in a sequence based on a seed
  100. '*
  101. '* The Seed procedure sets the starting point for generating a series
  102. '* of pseudo-random values. To re-initialize the generator with the same
  103. '* sequennce, use -1 as the seed argument. Use any positive seed value sets the generator to a random
  104. '* starting point.
  105. '*
  106. '* Calling Random or RandomReal before any call to Seed will generate a
  107. '* sequence based on the system timer.
  108. Sub Seed(Optional ByVal iSeed As Long = -1)
  109. Static iLastSeed As Long
  110. Select Case iSeed
  111. Case -1
  112. ' -1 reserved for reinitializing last sequence
  113. If iLastSeed Then iLast = iLastSeed Else iLast = Abs(timeGetTime)
  114. Exit Sub
  115. Case 0
  116. ' Algorithm won't handle 0 seed, so use it to represent system timer
  117. iLast = Abs(timeGetTime)
  118. Case Else
  119. iLast = Abs(iSeed)
  120. End Select
  121. iLastSeed = iLast
  122. End Sub
  123. ' Return current seed (save to reproduce a sequence later)
  124. Function GetSeed() As Long
  125. GetSeed = iLast
  126. End Function
  127. #If fComponent = 0 Then
  128. Private Sub ErrRaise(e As Long)
  129. Dim sText As String, sSource As String
  130. If e > 1000 Then
  131. sSource = App.ExeName & ".Random"
  132. Select Case e
  133. Case eeBaseRandom
  134. BugAssert True
  135. Case eeBaseIllegalRange
  136. sText = "Random: Range can't be greater than 2147483645"
  137. ' Case ee...
  138. ' Add additional errors
  139. End Select
  140. Err.Raise COMError(e), sSource, sText
  141. Else
  142. ' Raise standard Visual Basic error
  143. sSource = App.ExeName & ".VBError"
  144. Err.Raise e, sSource
  145. End If
  146. End Sub
  147. #End If